﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using WarehouseManagement.BusinessLogic.BC;
using WarehouseManagement.Shared;
using WarehouseManagement.Shared.Settings;

namespace WarehouseManagement.Views.Shared
{
    public partial class RestoreDataForm : DevExpress.XtraEditors.XtraForm
    {
        private BaseBC _bc;

        public RestoreDataForm()
        {
            InitializeComponent();
            _bc = new BaseBC();
        }

        private DatabaseSettings _settings;


        private void LoadSettings()
        {
            _settings = SettingsManager.ReadSettings(GlobalMemory.DatabaseSettingFilePath);
        }

        private void txtFilePath_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Ellipsis)
            {
                OpenFileDialog dia = new OpenFileDialog();
                //dia.RootFolder = Environment.SpecialFolder.MyComputer;
                //dia.ShowNewFolderButton = true;
                if (dia.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
                    return;
                txtFilePath.Text = dia.FileName;

            }
        }

        private void RestoreDataForm_Load(object sender, EventArgs e)
        {
            AssignFileName();
        }

        private void AssignFileName()
        {
            LoadSettings();
            txtDBName.Text = string.Format("{0}", _settings.DatabaseName);

        }
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnDo_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtFilePath.Text))
            {
                XtraMessageBox.Show("Bạn chưa chọn file", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Restore();
        }

        private void Restore()
        {
            Restore restoreDB = new Restore();
            restoreDB.Database = txtDBName.Text;
            /* Specify whether you want to restore database, files or log */
            restoreDB.Action = RestoreActionType.Database;
            restoreDB.Devices.AddDevice(txtFilePath.Text, DeviceType.File);

            /* You can specify ReplaceDatabase = false (default) to not create a new
             * database, the specified database must exist on SQL Server
             * instance. If you can specify ReplaceDatabase = true to create new
             * database image regardless of the existence of specified database with
             * the same name */
            restoreDB.ReplaceDatabase = true;

            /* If you have a differential or log restore after the current restore,
             * you would need to specify NoRecovery = true, this will ensure no
             * recovery performed and subsequent restores are allowed. It means it
             * the database will be in a restoring state. */
            //restoreDB.NoRecovery = true;

            /* Wiring up events for progress monitoring */
            restoreDB.PercentComplete += CompletionStatusInPercent;
            restoreDB.Complete += Restore_Completed;

            /* SqlRestore method starts to restore the database
             * You can also use SqlRestoreAsync method to perform restore 
             * operation asynchronously */
            //var myServer = new Server("BALAP-PC");
            var setting2 = new DatabaseSettings(_settings);
            setting2.DatabaseName = "master";
            var myServer = GetServerInfo(setting2);


            try
            {
                KillAllConnections(_settings.DatabaseName, setting2.ConnectionString);
            }
            catch
            {
            }
            try
            {
                restoreDB.SqlRestore(myServer);
            }

            catch (Exception ex)
            {
                XtraMessageBox.Show(string.Format("Không thể khôi phục dữ liệu. Xin hãy thử lại sau:\n{0}", ex.InnerException.Message), 
                    "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


        }

        private void KillAllConnections(string dbName, string conStr)
        {
            using (SqlConnection con = new SqlConnection(conStr))
            {
                using (SqlCommand cmd = new SqlCommand("usp_KillAllConnections", con))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.Add("@dbName", SqlDbType.VarChar).Value = dbName;


                    con.Open();
                    cmd.ExecuteNonQuery();
                }
            }
        }
        private Server GetServerInfo(DatabaseSettings settings)
        {
            var conStr = settings.ConnectionString;
            var sqlConn = new SqlConnection(conStr);
            var sqlServer = new Server(new ServerConnection(sqlConn));
            return sqlServer;
        }


        private void CompletionStatusInPercent(object sender, PercentCompleteEventArgs args)
        {
            pgProgress.EditValue = args.Percent;

            Application.DoEvents();
        }

        private void Restore_Completed(object sender, ServerMessageEventArgs args)
        {
            XtraMessageBox.Show(string.Format("{0}", args.Error.Message), "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
            _bc.RecycleContext();
            this.Close();
        }

        private void pgProgress_CustomDisplayText(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
        {
            e.DisplayText = string.Format("{0}%", e.Value);
            lblComplete.Text = e.DisplayText;
        }
    }
}